/*
 * CAD System for seamlessly constructing 2D and 3D scenes with aspects and motion
 * Copyright (C) 2013 Bernhard Haumacher and others
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package de.haumacher.draw5d.dataflow.core;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import de.haumacher.draw5d.dataflow.Observable;
import de.haumacher.draw5d.dataflow.Options;
import de.haumacher.draw5d.dataflow.Property;

public class OptionsImpl implements Options {

	private List<Property<? extends Observable>> _properties;

	private final Map<Property<?>, Observable> _values = new HashMap<Property<?>, Observable>();

	/**
	 * Creates a {@link Property} of the given type.
	 */
	public static <T> Property<T> property(Class<T> type) {
		return new PropertyImpl<T>(type);
	}

	public OptionsImpl(Property<? extends Observable>... properties) {
		_properties = Arrays.asList(properties);
	}

	@Override
	public List<Property<? extends Observable>> getProperties() {
		return _properties;
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T extends Observable> T get(Property<T> property) {
		return (T) _values.get(property);
	}

	@Override
	@SuppressWarnings("unchecked")
	public <T extends Observable> T set(Property<T> property, T value) {
		assert _properties.contains(property);
		return (T) _values.put(property, property.getType().cast(value));
	}

}
